home *** CD-ROM | disk | FTP | other *** search
/ Isometric Game Programming with DirectX 7.0 / Isometric Game Programming.iso / source / chapter18 / isohex18_2 / isohex18_2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-02  |  16.8 KB  |  692 lines

  1. /*****************************************************************************
  2. IsoHex18_2.cpp
  3. Ernest S. Pazera
  4. 31AUG2000
  5. Start a WIN32 Application Workspace, add in this file
  6. Requires the following libs:
  7. ddraw.lib, dxguid.lib
  8. Requires the following files:
  9. DDFuncs.h.cpp, GDICanvas.h/cpp, IsoMouseMap.h/cpp,
  10. IsoScroller.h/cpp, IsoTilePlotter.h/cpp, IsoTileWalker.h/cpp
  11. TileSet.h/cpp. IsoHexCore.h, IsoHexDefs.h
  12. IsoRenderer.h/cpp
  13. *****************************************************************************/
  14.  
  15. //////////////////////////////////////////////////////////////////////////////
  16. //INCLUDES
  17. //////////////////////////////////////////////////////////////////////////////
  18. #define WIN32_LEAN_AND_MEAN  
  19.  
  20. #include <windows.h>  
  21. #include "DDFuncs.h"
  22. #include "TileSet.h"
  23. #include "IsoHexCore.h"
  24. #include "IsoRenderer.h"
  25.  
  26.  
  27. //////////////////////////////////////////////////////////////////////////////
  28. //DEFINES
  29. //////////////////////////////////////////////////////////////////////////////
  30. //name for our window class
  31. #define WINDOWCLASS "ISOHEX18"
  32. //title of the application
  33. #define WINDOWTITLE "IsoHex 18-2"
  34.  
  35. const int MAPWIDTH=200;
  36. const int MAPHEIGHT=400;
  37.  
  38. //gamestates
  39. const int GS_IDLE=0;//waits for a keypress
  40. const int GS_STARTMOVE=1;//sets up the move
  41. const int GS_DOMOVE=2;//carries out the move
  42. const int GS_DONEMOVE=3;//finishes the move
  43.  
  44. //////////////////////////////////////////////////////////////////////////////
  45. //PROTOTYPES
  46. //////////////////////////////////////////////////////////////////////////////
  47. bool Prog_Init();//game data initalizer
  48. void Prog_Loop();//main game loop
  49. void Prog_Done();//game clean up
  50.  
  51. //////////////////////////////////////////////////////////////////////////////
  52. //GLOBALS
  53. //////////////////////////////////////////////////////////////////////////////
  54. HINSTANCE hInstMain=NULL;//main application handle
  55. HWND hWndMain=NULL;//handle to our main window
  56.  
  57. //game state
  58. int iGameState=GS_IDLE;
  59.  
  60. //directdraw
  61. LPDIRECTDRAW7 lpdd=NULL;
  62. LPDIRECTDRAWSURFACE7 lpddsMain=NULL;
  63. LPDIRECTDRAWSURFACE7 lpddsBack=NULL;
  64. LPDIRECTDRAWSURFACE7 lpddsFrame=NULL;
  65.  
  66. //tilesets
  67. CTileSet tsBack;//background
  68. CTileSet tsTree;//tree foreground
  69. CTileSet tsUnit;//unit
  70.  
  71. //isohexcore components
  72. CTilePlotter TilePlotter;//plotter
  73. CTileWalker TileWalker;//walker
  74. CScroller Scroller;//scroller
  75. CMouseMap MouseMap;//mousemap
  76. CRenderer Renderer;//renderer
  77.  
  78. POINT ptScroll;//keep track of how quickly we scroll
  79.  
  80. //keep track of unit location
  81. POINT ptUnit;//current position of the unit
  82. POINT ptUnitOld;//last position of the unit
  83. ISODIRECTION idMoveUnit;//direction of movement
  84. //unit offset
  85. POINT ptUnitOffset;
  86. int iUnitFrame=0;
  87.  
  88. //map location structure
  89. struct MapLocation
  90. {
  91.     bool bTree;//false=no tree; true=tree
  92.     bool bUnit;//false=no unit; true=unit;
  93. };
  94.  
  95. MapLocation mlMap[MAPWIDTH][MAPHEIGHT];//map array
  96.  
  97. //rendering functionprototype
  98. void RenderFunc(LPDIRECTDRAWSURFACE7 lpddsDst,RECT* rcClip,int xDst,int yDst,int xMap,int yMap);
  99.  
  100. //////////////////////////////////////////////////////////////////////////////
  101. //WINDOWPROC
  102. //////////////////////////////////////////////////////////////////////////////
  103. LRESULT CALLBACK TheWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
  104. {
  105.     //which message did we get?
  106.     switch(uMsg)
  107.     {
  108.     case WM_KEYDOWN:
  109.         {
  110.             switch(wParam)
  111.             {
  112.             case VK_ESCAPE:
  113.                 {
  114.                     DestroyWindow(hWndMain);
  115.                     return(0);
  116.                 }break;
  117.             case VK_NUMPAD1:
  118.                 {
  119.                     if(iGameState==GS_IDLE)
  120.                     {
  121.                         idMoveUnit=ISO_SOUTHWEST;
  122.                         iGameState=GS_STARTMOVE;
  123.                     }
  124.                 }break;
  125.             case VK_NUMPAD2:
  126.                 {
  127.                     if(iGameState==GS_IDLE)
  128.                     {
  129.                         idMoveUnit=ISO_SOUTH;
  130.                         iGameState=GS_STARTMOVE;
  131.                     }
  132.                 }break;
  133.             case VK_NUMPAD3:
  134.                 {
  135.                     if(iGameState==GS_IDLE)
  136.                     {
  137.                         idMoveUnit=ISO_SOUTHEAST;
  138.                         iGameState=GS_STARTMOVE;
  139.                     }
  140.                 }break;
  141.             case VK_NUMPAD4:
  142.                 {
  143.                     if(iGameState==GS_IDLE)
  144.                     {
  145.                         idMoveUnit=ISO_WEST;
  146.                         iGameState=GS_STARTMOVE;
  147.                     }
  148.                 }break;
  149.             case VK_NUMPAD6:
  150.                 {
  151.                     if(iGameState==GS_IDLE)
  152.                     {
  153.                         idMoveUnit=ISO_EAST;
  154.                         iGameState=GS_STARTMOVE;
  155.                     }
  156.                 }break;
  157.             case VK_NUMPAD7:
  158.                 {
  159.                     if(iGameState==GS_IDLE)
  160.                     {
  161.                         idMoveUnit=ISO_NORTHWEST;
  162.                         iGameState=GS_STARTMOVE;
  163.                     }
  164.                 }break;
  165.             case VK_NUMPAD8:
  166.                 {
  167.                     if(iGameState==GS_IDLE)
  168.                     {
  169.                         idMoveUnit=ISO_NORTH;
  170.                         iGameState=GS_STARTMOVE;
  171.                     }
  172.                 }break;
  173.             case VK_NUMPAD9:
  174.                 {
  175.                     if(iGameState==GS_IDLE)
  176.                     {
  177.                         idMoveUnit=ISO_NORTHEAST;
  178.                         iGameState=GS_STARTMOVE;
  179.                     }
  180.                 }break;
  181.             }
  182.         }break;
  183.     case WM_DESTROY://the window is being destroyed
  184.         {
  185.  
  186.             //tell the application we are quitting
  187.             PostQuitMessage(0);
  188.  
  189.             //handled message, so return 0
  190.             return(0);
  191.  
  192.         }break;
  193.     case WM_PAINT://the window needs repainting
  194.         {
  195.             //a variable needed for painting information
  196.             PAINTSTRUCT ps;
  197.             
  198.             //start painting
  199.             HDC hdc=BeginPaint(hwnd,&ps);
  200.  
  201.             /////////////////////////////
  202.             //painting code would go here
  203.             /////////////////////////////
  204.  
  205.             //end painting
  206.             EndPaint(hwnd,&ps);
  207.                         
  208.             //handled message, so return 0
  209.             return(0);
  210.         }break;
  211.     }
  212.  
  213.     //pass along any other message to default message handler
  214.     return(DefWindowProc(hwnd,uMsg,wParam,lParam));
  215. }
  216.  
  217.  
  218. //////////////////////////////////////////////////////////////////////////////
  219. //WINMAIN
  220. //////////////////////////////////////////////////////////////////////////////
  221. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
  222. {
  223.     //assign instance to global variable
  224.     hInstMain=hInstance;
  225.  
  226.     //create window class
  227.     WNDCLASSEX wcx;
  228.  
  229.     //set the size of the structure
  230.     wcx.cbSize=sizeof(WNDCLASSEX);
  231.  
  232.     //class style
  233.     wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  234.  
  235.     //window procedure
  236.     wcx.lpfnWndProc=TheWindowProc;
  237.  
  238.     //class extra
  239.     wcx.cbClsExtra=0;
  240.  
  241.     //window extra
  242.     wcx.cbWndExtra=0;
  243.  
  244.     //application handle
  245.     wcx.hInstance=hInstMain;
  246.  
  247.     //icon
  248.     wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
  249.  
  250.     //cursor
  251.     wcx.hCursor=LoadCursor(NULL,IDC_ARROW);
  252.  
  253.     //background color
  254.     wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  255.  
  256.     //menu
  257.     wcx.lpszMenuName=NULL;
  258.  
  259.     //class name
  260.     wcx.lpszClassName=WINDOWCLASS;
  261.  
  262.     //small icon
  263.     wcx.hIconSm=NULL;
  264.  
  265.     //register the window class, return 0 if not successful
  266.     if(!RegisterClassEx(&wcx)) return(0);
  267.  
  268.     //create main window
  269.     hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTITLE, WS_POPUP | WS_VISIBLE,0,0,320,240,NULL,NULL,hInstMain,NULL);
  270.  
  271.     //error check
  272.     if(!hWndMain) return(0);
  273.  
  274.     //if program initialization failed, then return with 0
  275.     if(!Prog_Init()) return(0);
  276.  
  277.     //message structure
  278.     MSG msg;
  279.  
  280.     //message pump
  281.     for(;;)    
  282.     {
  283.         //look for a message
  284.         if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  285.         {
  286.             //there is a message
  287.  
  288.             //check that we arent quitting
  289.             if(msg.message==WM_QUIT) break;
  290.             
  291.             //translate message
  292.             TranslateMessage(&msg);
  293.  
  294.             //dispatch message
  295.             DispatchMessage(&msg);
  296.         }
  297.  
  298.         //run main game loop
  299.         Prog_Loop();
  300.     }
  301.     
  302.     //clean up program data
  303.     Prog_Done();
  304.  
  305.     //return the wparam from the WM_QUIT message
  306.     return(msg.wParam);
  307. }
  308.  
  309. //////////////////////////////////////////////////////////////////////////////
  310. //INITIALIZATION
  311. //////////////////////////////////////////////////////////////////////////////
  312. bool Prog_Init()
  313. {
  314.     //create IDirectDraw object
  315.     lpdd=LPDD_Create(hWndMain,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT);
  316.  
  317.     //set display mode
  318.     lpdd->SetDisplayMode(640,480,16,0,0);
  319.  
  320.     //create primary surface
  321.     lpddsMain=LPDDS_CreatePrimary(lpdd,1);
  322.  
  323.     //get back buffer
  324.     lpddsBack=LPDDS_GetSecondary(lpddsMain);
  325.  
  326.     //create the frame buffer
  327.     lpddsFrame=LPDDS_CreateOffscreen(lpdd,640,480);
  328.  
  329.     //load in the mousemap
  330.     MouseMap.Load("MouseMap.bmp");
  331.  
  332.     //set up the tile plotter
  333.     TilePlotter.SetMapType(ISOMAP_DIAMOND);//diamond mode
  334.     TilePlotter.SetTileSize(MouseMap.GetWidth(),MouseMap.GetHeight());//grab width and height from mousemap
  335.  
  336.     //set up tile walker to diamond mode
  337.     TileWalker.SetMapType(ISOMAP_DIAMOND);
  338.  
  339.     //set up screeen space
  340.     RECT rcTemp;
  341.     SetRect(&rcTemp,0,0,640,480);
  342.     Scroller.SetScreenSpace(&rcTemp);
  343.  
  344.     //load in tiles and cursor
  345.     tsBack.Load(lpdd,"backgroundts.bmp");
  346.     tsTree.Load(lpdd,"treets.bmp");
  347.     tsUnit.Load(lpdd,"unit_warrior.bmp");
  348.  
  349.     //grab tile extent from tileset
  350.     CopyRect(&rcTemp,&tsBack.GetTileList()[0].rcDstExt);
  351.  
  352.     //calculate the worldspace
  353.     Scroller.CalcWorldSpace(&TilePlotter,&rcTemp,MAPWIDTH,MAPHEIGHT);
  354.  
  355.     //calculate the mousemap reference point
  356.     MouseMap.CalcReferencePoint(&TilePlotter,&rcTemp);
  357.  
  358.     //calculate anchor space
  359.     Scroller.CalcAnchorSpace();
  360.  
  361.     //set wrap modes for scroller
  362.     Scroller.SetHWrapMode(WRAPMODE_CLIP);
  363.     Scroller.SetVWrapMode(WRAPMODE_CLIP);
  364.  
  365.     //set scroller anchor to (0,0)
  366.     Scroller.GetAnchor()->x=0;
  367.     Scroller.GetAnchor()->y=0;
  368.  
  369.     //attach scrolelr and tilewalker to mousemap
  370.     MouseMap.SetScroller(&Scroller);
  371.     MouseMap.SetTileWalker(&TileWalker);
  372.  
  373.     //set up the map to a random tilefield
  374.     for(int x=0;x<MAPWIDTH;x++)
  375.     {
  376.         for(int y=0;y<MAPHEIGHT;y++)
  377.         {
  378.             mlMap[x][y].bTree=((rand()%2)==1);//random tree
  379.             mlMap[x][y].bUnit=false;//no unit
  380.         }
  381.     }
  382.  
  383.     //calculate the extent rect
  384.     RECT rcExtent;
  385.     CopyRect(&rcExtent,&tsBack.GetTileList()[0].rcDstExt);//set to background extent
  386.     UnionRect(&rcExtent,&rcExtent,&tsTree.GetTileList()[0].rcDstExt);//union with tree extent
  387.     UnionRect(&rcExtent,&rcExtent,&tsUnit.GetTileList()[0].rcDstExt);//union with unit extent
  388.  
  389.     //set up the renderer
  390.     Renderer.SetBackBuffer(lpddsBack);
  391.     Renderer.SetExtentRect(&rcExtent);
  392.     Renderer.SetFrameBuffer(lpddsFrame);
  393.     Renderer.SetMapSize(MAPWIDTH,MAPHEIGHT);
  394.     Renderer.SetMouseMap(&MouseMap);
  395.     Renderer.SetPlotter(&TilePlotter);
  396.     Renderer.SetRenderFunction(RenderFunc);
  397.     Renderer.SetScroller(&Scroller);
  398.     Renderer.SetUpdateRectCount(100);
  399.     Renderer.SetWalker(&TileWalker);
  400.  
  401.     //set the position of the unit
  402.     ptUnit.x=rand()%MAPWIDTH;
  403.     ptUnit.y=rand()%MAPHEIGHT;
  404.     ptUnitOld=ptUnit;//set the old position to the same position
  405.     mlMap[ptUnit.x][ptUnit.y].bUnit=true;//set the unit on the map
  406.  
  407.     //plot the position of the unit
  408.     POINT ptPos=TilePlotter.PlotTile(ptUnit);
  409.  
  410.     ptPos.x-=(Scroller.GetScreenSpaceWidth()/2);//center the unit horizontally
  411.     ptPos.y-=(Scroller.GetScreenSpaceHeight()/2);//center the unit vertically
  412.  
  413.     //set the anchor
  414.     Scroller.SetAnchor(&ptPos);
  415.     Scroller.WrapAnchor();
  416.  
  417.     //update the entire screenspace
  418.     Renderer.AddRect(Scroller.GetScreenSpace());
  419.  
  420.     return(true);//return success
  421. }
  422.  
  423. //////////////////////////////////////////////////////////////////////////////
  424. //CLEANUP
  425. //////////////////////////////////////////////////////////////////////////////
  426. void Prog_Done()
  427. {
  428.     //release frame buffer
  429.     LPDDS_Release(&lpddsFrame);
  430.  
  431.     //release main/back surfaces
  432.     LPDDS_Release(&lpddsMain);
  433.  
  434.     //release directdraw
  435.     LPDD_Release(&lpdd);
  436. }
  437.  
  438. //////////////////////////////////////////////////////////////////////////////
  439. //MAIN GAME LOOP
  440. //////////////////////////////////////////////////////////////////////////////
  441. void Prog_Loop()
  442. {
  443.     switch(iGameState)
  444.     {
  445.     case GS_STARTMOVE:
  446.         {
  447.             //remove the unit from the old position
  448.             mlMap[ptUnitOld.x][ptUnitOld.y].bUnit=false;
  449.  
  450.             //calculate new position(virtual new position)
  451.             switch(idMoveUnit)
  452.             {
  453.             case ISO_NORTH:
  454.             case ISO_NORTHEAST:
  455.             case ISO_NORTHWEST:
  456.             case ISO_WEST:
  457.                 {
  458.                     //move ptUnit
  459.                     ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
  460.                     //set the offset
  461.                     ptUnitOffset.x=0;
  462.                     ptUnitOffset.y=0;
  463.                     //place unit at old position
  464.                     mlMap[ptUnitOld.x][ptUnitOld.y].bUnit=true;
  465.                 }break;
  466.             case ISO_EAST:
  467.                 {
  468.                     //move ptUnit
  469.                     ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
  470.                     //set the offset
  471.                     ptUnitOffset.x=-64;
  472.                     ptUnitOffset.y=0;
  473.                     //place unit at new position
  474.                     mlMap[ptUnit.x][ptUnit.y].bUnit=true;
  475.                 }break;
  476.             case ISO_SOUTHEAST:
  477.                 {
  478.                     //move ptUnit
  479.                     ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
  480.                     //set the offset
  481.                     ptUnitOffset.x=-32;
  482.                     ptUnitOffset.y=-16;
  483.                     //place unit at new position
  484.                     mlMap[ptUnit.x][ptUnit.y].bUnit=true;
  485.                 }break;
  486.             case ISO_SOUTHWEST:
  487.                 {
  488.                     //move ptUnit
  489.                     ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
  490.                     //set the offset
  491.                     ptUnitOffset.x=32;
  492.                     ptUnitOffset.y=-16;
  493.                     //place unit at new position
  494.                     mlMap[ptUnit.x][ptUnit.y].bUnit=true;
  495.                 }break;
  496.             case ISO_SOUTH:
  497.                 {
  498.                     //move ptUnit
  499.                     ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
  500.                     //set the offset
  501.                     ptUnitOffset.x=0;
  502.                     ptUnitOffset.y=-32;
  503.                     //place unit at new position
  504.                     mlMap[ptUnit.x][ptUnit.y].bUnit=true;
  505.                 }break;
  506.             }
  507.  
  508.             //set unit frame to 0
  509.             iUnitFrame=0;
  510.  
  511.             //set the next gamestate
  512.             iGameState=GS_DOMOVE;
  513.  
  514.         }break;
  515.     case GS_DONEMOVE:
  516.         {
  517.             //finish the move, make sure the unit is positioned correctly
  518.             switch(idMoveUnit)
  519.             {
  520.             case ISO_NORTH:
  521.             case ISO_NORTHEAST:
  522.             case ISO_NORTHWEST:
  523.             case ISO_WEST:
  524.                 {
  525.                     //remove from old position
  526.                     mlMap[ptUnitOld.x][ptUnitOld.y].bUnit=false;
  527.                     //place on new position
  528.                     mlMap[ptUnit.x][ptUnit.y].bUnit=true;
  529.                 }break;
  530.             }
  531.  
  532.             //plot new tile's position
  533.             POINT ptPlot=TilePlotter.PlotTile(ptUnit);
  534.             ptPlot=Scroller.WorldToScreen(ptPlot);
  535.  
  536.             //set scrolling to 0,0
  537.             ptScroll.x=0;
  538.             ptScroll.y=0;
  539.  
  540.             //check for scrolling
  541.             if(ptPlot.x<0) ptScroll.x=-320;
  542.             if(ptPlot.y<0) ptScroll.y=-240;
  543.             if(ptPlot.x>=640) ptScroll.x=320;
  544.             if(ptPlot.y>=480) ptScroll.y=240;
  545.  
  546.             //scroll the frame
  547.             Renderer.ScrollFrame(ptScroll.x,ptScroll.y);
  548.  
  549.             //add update tiles
  550.             Renderer.AddTile(ptUnitOld.x,ptUnitOld.y);
  551.             Renderer.AddTile(ptUnit.x,ptUnit.y);
  552.  
  553.             //set ptUnitOffset to (0,0)
  554.             ptUnitOffset.x=0;
  555.             ptUnitOffset.y=0;
  556.             //set the old unit position to the current unit position
  557.             ptUnitOld=ptUnit;
  558.             //go to idling gamestate
  559.             iGameState=GS_IDLE;
  560.  
  561.             //update the frame
  562.             Renderer.UpdateFrame();
  563.  
  564.             //flip
  565.             lpddsMain->Flip(0,DDFLIP_WAIT);
  566.         }break;
  567.     case GS_DOMOVE:
  568.         {
  569.             //move the unit offset
  570.             switch(idMoveUnit)
  571.             {
  572.             case ISO_NORTH:
  573.                 {
  574.                     //change offset
  575.                     ptUnitOffset.x+=0;
  576.                     ptUnitOffset.y-=8;
  577.                 }break;
  578.             case ISO_NORTHEAST:
  579.                 {
  580.                     //change offset
  581.                     ptUnitOffset.x+=8;
  582.                     ptUnitOffset.y-=4;
  583.                 }break;
  584.             case ISO_EAST:
  585.                 {
  586.                     //change offset
  587.                     ptUnitOffset.x+=16;
  588.                     ptUnitOffset.y+=0;
  589.                 }break;
  590.             case ISO_SOUTHEAST:
  591.                 {
  592.                     //change offset
  593.                     ptUnitOffset.x+=8;
  594.                     ptUnitOffset.y+=4;
  595.                 }break;
  596.             case ISO_SOUTH:
  597.                 {
  598.                     //change offset
  599.                     ptUnitOffset.x+=0;
  600.                     ptUnitOffset.y+=8;
  601.                 }break;
  602.             case ISO_SOUTHWEST:
  603.                 {
  604.                     //change offset
  605.                     ptUnitOffset.x-=8;
  606.                     ptUnitOffset.y+=4;
  607.                 }break;
  608.             case ISO_WEST:
  609.                 {
  610.                     //change offset
  611.                     ptUnitOffset.x-=16;
  612.                     ptUnitOffset.y+=0;
  613.                 }break;
  614.             case ISO_NORTHWEST:
  615.                 {
  616.                     //change offset
  617.                     ptUnitOffset.x-=8;
  618.                     ptUnitOffset.y-=4;
  619.                 }break;
  620.             }
  621.  
  622.             //grab the update RECTs
  623.             RECT rcUpdate1,rcUpdate2;
  624.             CopyRect(&rcUpdate1,&Renderer.rcExtent);
  625.             CopyRect(&rcUpdate2,&Renderer.rcExtent);
  626.  
  627.             //plot the position of the units old position
  628.             POINT ptPlot=TilePlotter.PlotTile(ptUnitOld);
  629.             ptPlot=Scroller.WorldToScreen(ptPlot);
  630.             OffsetRect(&rcUpdate1,ptPlot.x,ptPlot.y);
  631.  
  632.             //plot the position of the unit's new position
  633.             ptPlot=TilePlotter.PlotTile(ptUnit);
  634.             ptPlot=Scroller.WorldToScreen(ptPlot);
  635.             OffsetRect(&rcUpdate2,ptPlot.x,ptPlot.y);
  636.  
  637.             //scroll the frame (0,0)
  638.             Renderer.ScrollFrame(0,0);
  639.  
  640.             //merge the two update RECTS
  641.             UnionRect(&rcUpdate1,&rcUpdate1,&rcUpdate2);
  642.  
  643.             //send update rect to the renderer
  644.             Renderer.AddRect(&rcUpdate1);
  645.  
  646.             //update the frame
  647.             Renderer.UpdateFrame();
  648.  
  649.             //flip to show the back buffer
  650.             lpddsMain->Flip(0,DDFLIP_WAIT);
  651.  
  652.             //increase the unit frame counter
  653.             iUnitFrame++;
  654.  
  655.             //check for done with gamestate
  656.             if(iUnitFrame==4)
  657.             {
  658.                 //set to the next gamestate
  659.                 iGameState=GS_DONEMOVE;
  660.             }
  661.  
  662.         }break;
  663.     case GS_IDLE://the game is idling, update the frame, but thats about it.
  664.         {
  665.             //scroll the frame (0,0)
  666.             Renderer.ScrollFrame(0,0);
  667.             //update the frame
  668.             Renderer.UpdateFrame();
  669.             //flip to show the back buffer
  670.             lpddsMain->Flip(0,DDFLIP_WAIT);
  671.         }break;
  672.     }
  673. }
  674.  
  675. void RenderFunc(LPDIRECTDRAWSURFACE7 lpddsDst,RECT* rcClip,int xDst,int yDst,int xMap,int yMap)
  676. {
  677.     //put background tile
  678.     tsBack.ClipTile(lpddsDst,rcClip,xDst,yDst,0);
  679.     //check for a tree
  680.     if(mlMap[xMap][yMap].bTree)
  681.     {
  682.         //put tree
  683.         tsTree.ClipTile(lpddsDst,rcClip,xDst,yDst,0);
  684.     }
  685.     //check for the unit
  686.     if(mlMap[xMap][yMap].bUnit)
  687.     {
  688.         //put unit
  689.         tsUnit.ClipTile(lpddsDst,rcClip,xDst+ptUnitOffset.x,yDst+ptUnitOffset.y,0);
  690.     }
  691. }
  692.